import tkinter as tk
from tkinter import ttk
from typing import Callable


class ModelSettings:
    """模型设置界面"""
    
    def __init__(self, parent_frame, config_manager=None, models: dict = None):
        self.parent_frame = parent_frame
        self.config_manager = config_manager
        self.models = models or {}
        
        # 变量
        self.model_var = None
        self.api_key_entry = None
        self.max_tokens_var = None
        self.temperature_var = None
        self.typing_speed_var = None
        
        # 回调函数
        self.on_model_change = None
        self.on_save_settings = None
        
        self.setup_model_settings_interface()
    
    def setup_model_settings_interface(self):
        """设置模型设置界面"""
        # 创建滚动框架
        canvas = tk.Canvas(self.parent_frame)
        scrollbar = ttk.Scrollbar(self.parent_frame, orient="vertical", command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
        # 模型选择设置
        self.setup_model_selection(scrollable_frame)
        
        # 模型参数设置
        self.setup_model_parameters(scrollable_frame)
        
        # 界面设置
        self.setup_ui_settings(scrollable_frame)
        
        # 保存按钮
        ttk.Button(scrollable_frame, text="保存模型设置", command=self._on_save_settings).pack(pady=10)
    
    def setup_model_selection(self, parent):
        """设置模型选择区域"""
        model_frame = ttk.LabelFrame(parent, text="模型选择", padding="10")
        model_frame.pack(fill=tk.X, pady=(0, 10))
        model_frame.columnconfigure(1, weight=1)
        
        ttk.Label(model_frame, text="选择模型:").grid(row=0, column=0, sticky=tk.W, pady=(0, 5))
        self.model_var = tk.StringVar()
        
        # 从配置文件获取模型列表
        model_names = []
        if self.config_manager:
            model_names = self.config_manager.get_model_names()
        else:
            model_names = list(self.models.keys())
        
        model_combo = ttk.Combobox(model_frame, textvariable=self.model_var, values=model_names, state="readonly")
        model_combo.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=(0, 5))
        model_combo.bind('<<ComboboxSelected>>', lambda e: self._on_model_change())
        
        # 显示当前模型信息
        self.model_info_label = ttk.Label(model_frame, text="", font=('TkDefaultFont', 8), foreground='gray')
        self.model_info_label.grid(row=1, column=1, sticky=tk.W, pady=(0, 5))
        
        ttk.Label(model_frame, text="API密钥:").grid(row=2, column=0, sticky=tk.W, pady=(0, 5))
        self.api_key_entry = ttk.Entry(model_frame, show="*", width=50)
        self.api_key_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), pady=(0, 5))
        
        # API密钥说明
        api_hint = ttk.Label(model_frame, text="请输入对应模型的API密钥", 
                            font=('TkDefaultFont', 8), foreground='gray')
        api_hint.grid(row=3, column=1, sticky=tk.W, pady=(0, 5))
    
    def setup_model_parameters(self, parent):
        """设置模型参数区域"""
        params_frame = ttk.LabelFrame(parent, text="模型参数", padding="10")
        params_frame.pack(fill=tk.X, pady=(0, 10))
        params_frame.columnconfigure(1, weight=1)
        
        ttk.Label(params_frame, text="最大令牌数:").grid(row=0, column=0, sticky=tk.W, pady=(0, 5))
        self.max_tokens_var = tk.StringVar(value="2000")
        max_tokens_spinbox = ttk.Spinbox(params_frame, from_=100, to=8000, textvariable=self.max_tokens_var, width=10)
        max_tokens_spinbox.grid(row=0, column=1, sticky=tk.W, pady=(0, 5))
        
        # 最大令牌数说明
        tokens_hint = ttk.Label(params_frame, text="控制模型生成文本的最大长度", 
                               font=('TkDefaultFont', 8), foreground='gray')
        tokens_hint.grid(row=1, column=1, sticky=tk.W, pady=(0, 5))
        
        ttk.Label(params_frame, text="温度 (0-2):").grid(row=2, column=0, sticky=tk.W, pady=(0, 5))
        self.temperature_var = tk.StringVar(value="0.7")
        temp_spinbox = ttk.Spinbox(params_frame, from_=0.0, to=2.0, increment=0.1, textvariable=self.temperature_var, width=10)
        temp_spinbox.grid(row=2, column=1, sticky=tk.W, pady=(0, 5))
        
        # 温度说明
        temp_hint = ttk.Label(params_frame, text="控制生成文本的随机性，0=确定性，2=最随机", 
                             font=('TkDefaultFont', 8), foreground='gray')
        temp_hint.grid(row=3, column=1, sticky=tk.W, pady=(0, 5))
    
    def setup_ui_settings(self, parent):
        """设置界面设置区域"""
        ui_frame = ttk.LabelFrame(parent, text="界面设置", padding="10")
        ui_frame.pack(fill=tk.X, pady=(0, 10))
        ui_frame.columnconfigure(1, weight=1)
        
        ttk.Label(ui_frame, text="打字速度(ms):").grid(row=0, column=0, sticky=tk.W, pady=(0, 5))
        self.typing_speed_var = tk.StringVar(value="50")
        typing_spinbox = ttk.Spinbox(ui_frame, from_=10, to=200, textvariable=self.typing_speed_var, width=10)
        typing_spinbox.grid(row=0, column=1, sticky=tk.W, pady=(0, 5))
        
        # 打字速度说明
        typing_hint = ttk.Label(ui_frame, text="控制AI回复时的打字动画速度", 
                               font=('TkDefaultFont', 8), foreground='gray')
        typing_hint.grid(row=1, column=1, sticky=tk.W, pady=(0, 5))
    
    def update_model_info(self):
        """更新模型信息显示"""
        if self.model_var and self.config_manager:
            model_name = self.model_var.get()
            models_config = self.config_manager.get_models_from_config()
            
            for model_id, model_info in models_config.items():
                if model_info.get('name') == model_name:
                    provider = model_info.get('provider', '未知')
                    description = model_info.get('description', '无描述')
                    info_text = f"提供商: {provider} | {description}"
                    self.model_info_label.config(text=info_text)
                    break
            else:
                self.model_info_label.config(text="")
    
    def get_settings(self) -> dict:
        """获取模型设置"""
        return {
            'model': self.model_var.get() if self.model_var else "",
            'api_key': self.api_key_entry.get() if self.api_key_entry else "",
            'max_tokens': self.max_tokens_var.get() if self.max_tokens_var else "2000",
            'temperature': self.temperature_var.get() if self.temperature_var else "0.7",
            'typing_speed': self.typing_speed_var.get() if self.typing_speed_var else "50"
        }
    
    def load_settings(self, settings: dict):
        """加载模型设置"""
        if self.model_var and 'model' in settings:
            self.model_var.set(settings['model'])
            self.update_model_info()
        
        if self.api_key_entry and 'api_key' in settings:
            self.api_key_entry.delete(0, tk.END)
            self.api_key_entry.insert(0, settings['api_key'])
        
        if self.max_tokens_var and 'max_tokens' in settings:
            self.max_tokens_var.set(settings['max_tokens'])
        
        if self.temperature_var and 'temperature' in settings:
            self.temperature_var.set(settings['temperature'])
        
        if self.typing_speed_var and 'typing_speed' in settings:
            self.typing_speed_var.set(settings['typing_speed'])
    
    def set_callbacks(self, on_model_change: Callable[[], None], on_save_settings: Callable[[], None]):
        """设置回调函数"""
        self.on_model_change = on_model_change
        self.on_save_settings = on_save_settings
    
    def _on_model_change(self):
        """模型改变事件"""
        self.update_model_info()
        if self.on_model_change:
            self.on_model_change()
    
    def _on_save_settings(self):
        """保存设置事件"""
        if self.on_save_settings:
            self.on_save_settings()